package com.twu.biblioteca.model.menu;

import com.twu.biblioteca.model.IFactory;
import com.twu.biblioteca.model.LibraryCatalogue;
import com.twu.biblioteca.model.WrapperObject;
import com.twu.biblioteca.model.item.ItemFormatter;
import com.twu.biblioteca.model.item.books.BookFormatter;
import com.twu.biblioteca.model.item.movies.MovieFormatter;
import com.twu.biblioteca.model.session.Session;
import com.twu.biblioteca.model.session.SessionManager;
import com.twu.biblioteca.model.users.UserFormatter;
import com.twu.biblioteca.model.users.UserManager;
import com.twu.biblioteca.presenter.*;
import com.twu.biblioteca.view.*;
import com.twu.biblioteca.view.utils.InputSystem;
import com.twu.biblioteca.view.utils.OutputSystem;

import java.io.PrintStream;

/**
 * Created with IntelliJ IDEA.
 * User: cschlumb
 * Date: 16/08/2013
 * Time: 16:22
 * To change this template use File | Settings | File Templates.
 */
public class MenuBuilder {

    private MenuBuilder() {}

    public static Menu defaultMenu(LibraryCatalogue libraryCatalogue,
                                   UserManager userManager,
                                   SessionManager sessionManager,
                                   WrapperObject<Boolean> systemExit){
        Menu menu = new Menu();

        menu.addPublicItem(0, getListBookMenuItem(libraryCatalogue));
        menu.addPublicItem(1, getListMoviesMenuItem(libraryCatalogue));
        menu.addPublicItem(2, getMembershipMenuItem(sessionManager, userManager));
        menu.addPublicItem(3, getLoginMenuItem(userManager, sessionManager));
        menu.addPublicItem(4, getExitMenuItem(systemExit));

        menu.addPrivateItem(0, getListBookMenuItem(libraryCatalogue));
        menu.addPrivateItem(1, getListMoviesMenuItem(libraryCatalogue));
        menu.addPrivateItem(2, getMembershipMenuItem(sessionManager, userManager));
        menu.addPrivateItem(3, getReserveMenuItem(libraryCatalogue));
        menu.addPrivateItem(4, getLogoutMenuItem(sessionManager));
        menu.addPrivateItem(5, getExitMenuItem(systemExit));

        return menu;
    }

    private static IMenu getListBookMenuItem(final LibraryCatalogue libraryCatalogue){
        IFactory<Presenter> factoryPresenter = new IFactory<Presenter>() {
            @Override
            public Presenter get() {
                return new BookPresenter(libraryCatalogue, new BookFormatter(), new ItemListView(new OutputSystem(System.out)));
            }
        };

        return new MenuItem("List books", factoryPresenter);
    }

    private static IMenu getListMoviesMenuItem(final LibraryCatalogue libraryCatalogue){
        IFactory<Presenter> factoryPresenter = new IFactory<Presenter>() {
            @Override
            public Presenter get() {
                return new MoviePresenter(libraryCatalogue, new MovieFormatter(), new ItemListView(new OutputSystem(System.out)));
            }
        };

        return new MenuItem("List movies", factoryPresenter);
    }

    private static IMenu getMembershipMenuItem(final SessionManager sessionManager,
                                               final UserManager userManager){
        IFactory<Presenter> factoryPresenter = new IFactory<Presenter>() {
            @Override
            public Presenter get() {
                return new MembershipPresenter(sessionManager, userManager, new UserFormatter(), new MembershipView(new OutputSystem(System.out)));
            }
        };

        return new MenuItem("Check membership", factoryPresenter);
    }

    private static IMenu getReserveMenuItem(final LibraryCatalogue libraryCatalogue){
        IFactory<Presenter> factoryPresenter = new IFactory<Presenter>() {
            @Override
            public Presenter get() {
                return new ReservationPresenter(libraryCatalogue, new ReservationView(new OutputSystem(System.out), new InputSystem(System.in)));
            }
        };

        return new MenuItem("Reserve", factoryPresenter);
    }

    private static IMenu getLoginMenuItem(final UserManager userManager,
                                          final SessionManager sessionManager){
        IFactory<Presenter> factoryPresenter = new IFactory<Presenter>() {
            @Override
            public Presenter get() {
                return new LoginPresenter(new LoginView(new OutputSystem(System.out), new InputSystem(System.in)), userManager, sessionManager);
            }
        };

        return new MenuItem("Login", factoryPresenter);
    }

    private static IMenu getLogoutMenuItem(final SessionManager sessionManager){
        IFactory<Presenter> factoryPresenter = new IFactory<Presenter>() {
            @Override
            public Presenter get() {
                return new LogoutPresenter(sessionManager, new LogoutView(new OutputSystem(System.out)));
            }
        };

        return new MenuItem("Logout", factoryPresenter);
    }

    private static IMenu getExitMenuItem(final WrapperObject<Boolean> systemExit){
        IFactory<Presenter> factoryPresenter = new IFactory<Presenter>() {
            @Override
            public Presenter get() {
                return new Presenter() {
                    @Override
                    public void go(Session session) {
                        systemExit.setValue(true);
                    }
                };
            }
        };

        return new MenuItem("Exit", factoryPresenter);
    }
}
